
from abc import abstractmethod
import pandas as pd
from pandas._libs.missing import NAType
from pandas._libs.tslibs import NaTType
from pandas.core.algorithms import isin
from pandas.core.dtypes.common import is_period_dtype
import json


class Jsonable():

    @abstractmethod
    def _2json(self):
        pass


def json_defalut(obj):

    if isinstance(obj, Jsonable):
        return obj._2json()

    if isinstance(obj, pd.DataFrame):
        obj = obj.copy()
        timedeltas = obj.select_dtypes(
            include=["timedelta", 'datetime']).columns
        if len(timedeltas):
            obj[timedeltas] = obj[timedeltas].applymap(lambda x: x.isoformat())
        # Convert PeriodIndex to datetimes before serializing
        if is_period_dtype(obj.index):
            obj.index = obj.index.to_timestamp()

        return obj.fillna('').to_dict(orient="records")

    if isinstance(obj, pd.Timestamp):
        return obj.isoformat()

    # if isinstance(obj, Python_call):
    #     pass

    if isinstance(obj, (NaTType, NAType)):
        return ''

    return str(obj)


def tojson(data):
    return json.dumps(data, default=json_defalut, ensure_ascii=False)
